<template>
  <div class="page-wrap">
    <a-card title="部门管理" :bordered="false">
      <template #extra>
        <a-space>
          <a-input v-model="keyword" placeholder="部门名关键词" allow-clear style="width: 200px" />
          <a-button type="primary" @click="filterTree">查询</a-button>
          <a-button @click="resetFilter">重置</a-button>
          <a-button type="primary" status="success" @click="openEdit()">新增</a-button>
        </a-space>
      </template>

      <a-row :gutter="16">
        <a-col :span="8">
          <a-tree
            :data="treeData"
            :field-names="{ key: 'departmentId', title: 'departmentName', children: 'children' }"
            @select="onSelect"
            :selected-keys="selectedKeys"
          />
        </a-col>
        <a-col :span="16">
          <a-table :data="tableData" row-key="departmentId">
            <a-table-column title="ID" data-index="departmentId" width="100" />
            <a-table-column title="部门名称" data-index="departmentName" />
            <a-table-column title="排序" data-index="sort" width="100" />
            <a-table-column title="操作" :width="220">
              <template #cell="{ record }">
                <a-space>
                  <a-button type="text" @click="openEdit(record)">编辑</a-button>
                  <a-popconfirm content="确认删除该部门？" @ok="onDelete(record)">
                    <a-button type="text" status="danger">删除</a-button>
                  </a-popconfirm>
                </a-space>
              </template>
            </a-table-column>
          </a-table>
        </a-col>
      </a-row>
    </a-card>

    <a-modal v-model:visible="editVisible" :title="editing?.departmentId ? '编辑部门' : '新增部门'" :mask-closable="false" @ok="saveDept" :confirm-loading="saving">
      <a-form :model="editing" layout="vertical">
        <a-form-item field="parentId" label="上级部门">
          <a-tree-select
            v-model="editing.parentId"
            :data="treeData"
            :field-names="{ key: 'departmentId', title: 'departmentName', children: 'children' }"
            allow-clear
            placeholder="选择上级部门"
          />
        </a-form-item>
        <a-form-item field="departmentName" label="部门名称" :rules="[{ required: true, message: '请输入部门名称' }]">
          <a-input v-model="editing.departmentName" />
        </a-form-item>
        <a-form-item field="sort" label="排序">
          <a-input-number v-model="(editing as any).sort" :min="0" />
        </a-form-item>
      </a-form>
    </a-modal>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted } from 'vue';
import { Message } from '@arco-design/web-vue';
import { deptTree, deptAdd, deptUpdate, deptDelete, type Dept } from '@/api/system';

const rawTree = ref<any[]>([]);
const treeData = ref<any[]>([]);
const keyword = ref('');
const selectedKeys = ref<number[]>([]);
const tableData = ref<any[]>([]);

function buildFlatList(nodes: any[], pid?: number, list: any[] = []) {
  for (const n of nodes) {
    (n as any)._pid = pid;
    list.push(n);
    if (n.children && n.children.length) {
      buildFlatList(n.children, n.departmentId, list);
    }
  }
  return list;
}

function filterTree() {
  if (!keyword.value) {
    treeData.value = JSON.parse(JSON.stringify(rawTree.value));
    onSelect(selectedKeys.value);
    return;
  }
  const list = buildFlatList(rawTree.value);
  const ids = new Set(list.filter(x => (x.departmentName || '').includes(keyword.value)).map(x => x.departmentId));
  const clone = JSON.parse(JSON.stringify(rawTree.value));
  function dfs(nodes: any[]): any[] {
    return nodes
      .map(n => ({ ...n, children: n.children ? dfs(n.children) : [] }))
      .filter(n => ids.has(n.departmentId) || (n.children && n.children.length));
  }
  treeData.value = dfs(clone);
  onSelect([]);
}
function resetFilter() {
  keyword.value = '';
  treeData.value = JSON.parse(JSON.stringify(rawTree.value));
  onSelect([]);
}

function onSelect(keys: number[]) {
  selectedKeys.value = keys;
  if (!keys.length) {
    tableData.value = buildFlatList(rawTree.value).filter(Boolean);
  } else {
    const list = buildFlatList(rawTree.value);
    const ids = new Set<number>();
    const childrenOf = (id: number) => list.filter(x => (x as any)._pid === id).map(x => x.departmentId);
    const take = (id: number) => {
      ids.add(id);
      for (const c of childrenOf(id)) take(c);
    };
    for (const id of keys) take(id);
    tableData.value = list.filter(x => ids.has(x.departmentId));
  }
}

const editVisible = ref(false);
const saving = ref(false);
const editing = reactive<Partial<Dept & { sort?: number }>>({});

function openEdit(row?: any) {
  editVisible.value = true;
  Object.assign(editing, { departmentId: undefined, parentId: undefined, departmentName: '', sort: 0 });
  if (row?.departmentId) Object.assign(editing, row);
}

async function saveDept() {
  saving.value = true;
  try {
    if ((editing as any).departmentId) {
      await deptUpdate(editing as any);
      Message.success('已保存');
    } else {
      await deptAdd(editing as any);
      Message.success('已新增');
    }
    editVisible.value = false;
    await loadTree();
  } finally {
    saving.value = false;
  }
}

async function onDelete(row: any) {
  await deptDelete([row.departmentId]);
  Message.success('已删除');
  await loadTree();
}

async function loadTree() {
  const res = await deptTree();
  rawTree.value = res.data || [];
  treeData.value = JSON.parse(JSON.stringify(rawTree.value));
  onSelect([]);
}

onMounted(loadTree);
</script>

<style scoped>
.page-wrap { padding: 12px; }
</style>